package com.ayf.payment.game.api.service.ehb.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.ayb.handler.AybUserTransferHandler;
import com.ayf.payment.game.api.config.RequestConfig;
import com.ayf.payment.game.api.config.SystemInitialization;
import com.ayf.payment.game.api.dto.MerchantDTO;
import com.ayf.payment.game.api.dto.ayb.MerchantTwoDTO;
import com.ayf.payment.game.api.dto.ayb.SignPayProductDTO;
import com.ayf.payment.game.api.dto.ayf.AyfSplitOrderBindDTO;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.httpclient.HttpUtils;
import com.ayf.payment.game.api.mapper.ayb.AybUserTransferBindMapper;
import com.ayf.payment.game.api.service.MerchantService;
import com.ayf.payment.game.api.service.SignPayProductService;
import com.ayf.payment.game.api.service.ehb.EhbSplitOrderBindService;
import com.ayf.payment.game.api.service.platform.PaymentChannelService;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.ayf.payment.game.api.utils.ValidateUtil;
import com.swwx.charm.commons.lang.utils.LogPortal;
import com.swwx.charm.zookeeper.lock.DistributedLock;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class EhbSplitOrderBindServiceImpl implements EhbSplitOrderBindService {

	private static final String PLATFORM_CODE = System.getenv("GAME_AYFPAY_PLATFORM_CODE");

	@Resource
	public SystemInitialization systemInitialization;
	@Resource
	private MerchantService merchantService;
	@Resource
	private AybUserTransferHandler aybUserTransferHandler;
	@Resource
	private PaymentChannelService paymentChannelService;

	@Resource
	private AybUserTransferBindMapper aybUserTransferBindMapper;
	@Resource
	private SignPayProductService signPayProductService;


	@Autowired
	protected DistributedLock distributedLock;




	/**
	 * 绑定分账通分账
	 * @author lch
	 * @date 2022/1/19
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void bind(MerchantDTO merchantDTO, AyfSplitOrderBindDTO dto) {
		String traceId = SnowFlakeUtils.getTraceId();

		PaymentChannelDTO paymentChannelDTO = this.paymentChannelService.getPaymentChannelByCode("AYF_SPLIT_PAY");

		SignPayProductDTO signPayProduct = signPayProductService.getByMerchantIdAndPayCode(merchantDTO.getId(), "AYF_SPLIT_PAY");
		ValidateUtil.businessValidate(signPayProduct==null||signPayProduct.getCountSignPayProduct()==0, "已绑定，请勿重复操作");

		Map<String, String> result = new HashMap<>(16);

		Map<String, Object> reqMap = new HashMap<>(16);
		reqMap.put("platformCode", PLATFORM_CODE);
		reqMap.put("merchantId", paymentChannelDTO.getAccountNumber());
		reqMap.put("customerMerchantId", merchantDTO.getId());
		reqMap.put("customerMerchantUserName", merchantDTO.getName());
		reqMap.put("ehbMerchantSecretKey", dto.getEhbSubMerchantSecretKey());

		String channelPayUrl = paymentChannelDTO.getPaymentUrl();
		if (channelPayUrl.endsWith("/")){
			channelPayUrl=channelPayUrl.substring(0,channelPayUrl.lastIndexOf("/"));
		}
		String url = channelPayUrl + RequestConfig.AYF_SPLIT_PAY_BIND;
		String reqStr = JSONObject.toJSONString(reqMap);
		LogPortal.info("{} 商户ID[{}] 【解绑分账通分账】请求参数[{}]", traceId, merchantDTO.getId(), reqStr);
		try {
			MerchantDTO mDto = new MerchantDTO();
			mDto.setMerchantSecretKey(paymentChannelDTO.getChannelKey());
			mDto.setPrivateKey(paymentChannelDTO.getPlatformPrivateKey());
			mDto.setPublicKey(paymentChannelDTO.getChannelPublicKey());
			result = HttpUtils.doPost(traceId, url, reqStr, mDto);
			LogPortal.info("{} 商户ID[{}] 调用【绑定分账通分账】接口成功，响应报文:{}", traceId, merchantDTO.getId(), result);
		}catch (Exception e) {
			LogPortal.error("{} 商户ID[{}] 【绑定分账通分账】失败，发生了{}异常，错误描述:{}", e, traceId, merchantDTO.getId(), e.getClass().getName(), e.getMessage());
			throw new NullSetException("绑定分账通分账失败，错误描述："+e.getMessage());
		}
		if (result == null) {
			throw new NullSetException("绑定分账通分账失败，请稍后重试！");
		}

		String responseCode = result.get(HttpUtils.RESPONSE_CODE);
		String response_data = result.get(HttpUtils.RESPONSE_DATA);
		if (!"200".equals(responseCode)) {
			LogPortal.error(" {} 商户ID[{}] 【绑定分账通分账】失败，HTTP状态码[{}] 响应报文:{}", traceId, merchantDTO.getId(), responseCode, response_data);
			throw new NullSetException("绑定分账通分账失败，请稍后重试！");
		}

		JSONObject data = null;
		try {
			data = JSON.parseObject(response_data);
		} catch (Exception e) {
			LogPortal.error("{} 商户ID[{}]【绑定分账通分账】失败，支付渠道响应内容格式错误，解析内容发生了异常:{}，响应报文:{}", e, traceId, merchantDTO.getId(), e.getMessage(), response_data);
			throw new NullSetException("绑定分账通分账失败，请稍后重试！");
		}
		String return_code = data.getString("return_code");
		if ("FAIL".equals(return_code)) {
			LogPortal.error("{} 商户ID[{}] 【绑定分账通分账】失败，失败原因:{}", traceId, merchantDTO.getId(), data.get("return_msg"));
			throw new NullSetException("绑定分账通分账失败："+data.get("return_msg"));
		}
		String err_code = data.getString("err_code");
		if (HttpUtils.SUCCESS_CODE.equals(return_code) && StringUtils.isBlank(err_code)) {
			SignPayProductDTO payProductDTO = new SignPayProductDTO();
			payProductDTO.setChannelMerchantId(data.getString("subChannelMerchantId"));
			payProductDTO.setMerchantId(merchantDTO.getId());
			payProductDTO.setPayCode("AYF_SPLIT_PAY");
			MerchantTwoDTO merchantTwoDTO = new MerchantTwoDTO();
			merchantTwoDTO.setChannelMerchantId(data.getString("subChannelMerchantId"));
			payProductDTO.setMerchantTwoDTO(merchantTwoDTO);
			payProductDTO.setApplyStatus(2);
			LogPortal.info("SignPayProductDTO:{}", JSONObject.toJSONString(payProductDTO));
			this.signPayProductService.insertSignPayProduct(payProductDTO);

		} else {
			String err_code_desc = data.getString("err_code_desc");
			LogPortal.error("{} 商户ID[{}] 【绑定分账通分账】失败，支付渠道错误码[{}] 错误码描述[{}]", traceId, merchantDTO.getId(), err_code, err_code_desc);
			throw new NullSetException("绑定分账通分账失败:"+err_code_desc);
		}

	}

	/**
	 * 解绑分账通分账
	 * @author lch
	 * @date 2022/1/20
	 */
	@Override
	public void unBind(MerchantDTO merchantDTO) {
		String traceId = SnowFlakeUtils.getTraceId();

		PaymentChannelDTO paymentChannelDTO = this.paymentChannelService.getPaymentChannelByCode("AYF_SPLIT_PAY");

		SignPayProductDTO signPayProduct = signPayProductService.getByMerchantIdAndPayCode(merchantDTO.getId(), "AYF_SPLIT_PAY");
		ValidateUtil.businessValidate(signPayProduct!=null&&signPayProduct.getCountSignPayProduct()>0, "已解绑，请勿重复操作");

		Map<String, String> result = new HashMap<>(16);

		Map<String, Object> reqMap = new HashMap<>(16);
		reqMap.put("platformCode", PLATFORM_CODE);
		reqMap.put("merchantId", paymentChannelDTO.getAccountNumber());
		reqMap.put("subMerchantId", signPayProduct.getChannelMerchantId());
		reqMap.put("customerMerchantId", merchantDTO.getId());
		reqMap.put("customerMerchantUserName", merchantDTO.getName());

		String channelPayUrl = paymentChannelDTO.getPaymentUrl();
		if (channelPayUrl.endsWith("/")){
			channelPayUrl=channelPayUrl.substring(0,channelPayUrl.lastIndexOf("/"));
		}
		String url = channelPayUrl + RequestConfig.AYF_SPLIT_PAY_UNBIND;
		String reqStr = JSONObject.toJSONString(reqMap);
		LogPortal.info("{} 商户ID[{}] 【解绑分账通分账】请求参数[{}]", traceId, merchantDTO.getId(), reqStr);
		try {
			MerchantDTO mDto = new MerchantDTO();
			mDto.setMerchantSecretKey(paymentChannelDTO.getChannelKey());
			mDto.setPrivateKey(paymentChannelDTO.getPlatformPrivateKey());
			mDto.setPublicKey(paymentChannelDTO.getChannelPublicKey());
			result = HttpUtils.doPost(traceId, url, reqStr, mDto);
			LogPortal.info("{} 商户ID[{}] 调用【解绑分账通分账】接口成功，响应报文:{}", traceId, merchantDTO.getId(), result);
		} catch (Exception e) {
			LogPortal.error("{} 商户ID[{}] 【解绑分账通分账】失败，发生了{}异常，错误描述:{}", e, traceId, merchantDTO.getId(), e.getClass().getName(), e.getMessage());
		}
		if (result == null) {
			throw new NullSetException("解绑分账通分账失败，请稍后重试！");
		}

		String responseCode = result.get(HttpUtils.RESPONSE_CODE);
		String response_data = result.get(HttpUtils.RESPONSE_DATA);
		if (!"200".equals(responseCode)) {
			LogPortal.error(" {} 商户ID[{}] 【解绑分账通分账】失败，HTTP状态码[{}] 响应报文:{}", traceId, merchantDTO.getId(), responseCode, response_data);
			throw new NullSetException("解绑分账通分账失败，请稍后重试！");
		}

		JSONObject data = null;
		try {
			data = JSON.parseObject(response_data);
		} catch (Exception e) {
			LogPortal.error("{} 商户ID[{}]【绑定分账通分账】失败，支付渠道响应内容格式错误，解析内容发生了异常:{}，响应报文:{}", e, traceId, merchantDTO.getId(), e.getMessage(), response_data);
			throw new NullSetException("解绑分账通分账失败，请稍后重试！");
		}
		String return_code = data.getString("return_code");
		if ("FAIL".equals(return_code)) {
			LogPortal.error("{} 商户ID[{}] 【绑定分账通分账】失败，失败原因:{}", traceId, merchantDTO.getId(), data.get("return_msg"));
			throw new NullSetException("解绑分账通分账失败，请稍后重试！");
		}
		String err_code = data.getString("err_code");
		if (HttpUtils.SUCCESS_CODE.equals(return_code) && (StringUtils.isBlank(err_code)||HttpUtils.SUCCESS_CODE.equals(err_code))) {
			//删除
			this.signPayProductService.removeById(signPayProduct.getId());

		} else {
			String err_code_desc = data.getString("err_code_desc");
			LogPortal.error("{} 商户ID[{}] 【解绑分账通分账】失败，支付渠道错误码[{}] 错误码描述[{}]", traceId, merchantDTO.getId(), err_code, err_code_desc);
			throw new NullSetException("解绑分账通分账失败，请稍后重试！");
		}

	}

	/**
	 * 获取分账通分账绑定信息
	 * @author lch
	 * @date 2022/1/25
	 */
	@Override
	public SignPayProductDTO getBindResult(MerchantDTO merchantDTO) {
		SignPayProductDTO productDTO = this.signPayProductService.getByMerchantIdAndPayCode(merchantDTO.getId(), "AYF_SPLIT_PAY");
		return productDTO;
	}

}
